/*
 * Copyright (C) 2008-2011 CBDP Consortium
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: 	Xabier Laiseca <xabier.laiseca@deusto.es>
 * 			David Ausín <david.ausin@deusto.es>
 */
package cbdp.server.contextreasoner.impl.reasoner.pellet;

import java.io.InputStream;

import org.mindswap.pellet.jena.PelletReasoner;
import org.mindswap.pellet.jena.PelletReasonerFactory;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.shared.Lock;

import cbdp.server.contextreasoner.exceptions.ReasonerException;
import cbdp.server.contextreasoner.impl.reasoner.RuleSet;

/**
 * @author  David Ausín (University of Deusto)
 */
public class PelletRuleSet implements RuleSet {

	private PelletReasoner reasoner;
	private OntModel model;
	private InputStream rules;

	@Override
	public void destroy() {

	}

	@Override
	public boolean launch()
	{
		model.enterCriticalSection(Lock.READ);
		final InfModel inferred;
		
		try
		{
			inferred = ModelFactory.createInfModel(reasoner, model);

		}
		finally
		{
			model.leaveCriticalSection();
		}

		// DON'T USE inferred.getDeductionsModel() because it always returns
		// null
		// see
		// http://lists.owldl.com/pipermail/pellet-users/2008-July/002858.html
		final Model inferences = ModelFactory.createDefaultModel();
		inferences.add(inferred);
		inferences.remove(inferred.getRawModel());

		if(inferences.isEmpty())
		{
			model.enterCriticalSection(Lock.WRITE);

			try
			{
				model.add(inferences);
			}
			finally
			{
				model.leaveCriticalSection();
			}
			
			return true;
		}
		else return false;
	}

	@Override
	public void load() throws ReasonerException {
		OntModel ontRules = ModelFactory
				.createOntologyModel(PelletReasonerFactory.THE_SPEC);
		ontRules.getDocumentManager().setFileManager(model.getDocumentManager().getFileManager());
		ontRules.read(rules, null);

		reasoner = new PelletReasoner(ontRules.getGraph());

	}

	@Override
	public void setOntModel(OntModel ontModel) {
		model = ontModel;

	}

	/**
	 * @param rules
	 * @uml.property  name="rules"
	 */
	@Override
	public void setRules(InputStream rules) {
		this.rules = rules;

	}

}
